package cn._2dland.websocket.io;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

import cn._2dland.websocket.model.message.BinaryMessage;
import cn._2dland.websocket.model.message.ControlMessage;
import cn._2dland.websocket.model.message.Message;
import cn._2dland.websocket.model.message.TextMessage;

/**
 * for hybi ver. 0.0~7.0
 * 
 * @author deadblue
 */
public class MessageInputStreamV00 extends MessageInputStream {
	
	public MessageInputStreamV00(InputStream in) {
		super(in);
	}

	@Override
	public Message readMessage() throws IOException {
		Message msg = null;
		int type = in.read();
		if(type < 0) {
			msg = new ControlMessage(ControlMessage.CLOSE);
		} else {
			if((type & 0x80) == 0x80) {
				msg = readBinaryMessage(type);
			} else {
				msg = readTextMessage(type);
			}
		}

		return msg;
	}

	/**
	 * 读取二进制报文
	 * 
	 * @param type 消息头
	 * @return
	 * @throws IOException
	 */
	private Message readBinaryMessage(int type) throws IOException {
		Message msg = null;

		// 获取二进制数据长度
		long length = 0;
		int b = 0;
		do {
			b = in.read();
			if(b < 0) break;

			length <<= 7;
			length |= (b & 0x7f);
		} while((b & 0x80) == 0x80);

		// 判断是否为结束报文
		if(type == 0xff && length ==0) {
			// type为0xff，且长度为0时，表示这是一个关闭报文
			msg = new ControlMessage(ControlMessage.CLOSE);
		} else {
			// 读取数据到缓冲区
			ByteArrayOutputStream buf = new ByteArrayOutputStream();
			for(int i = 0; i < length; i++) {
				buf.write(in.read());
			}
			buf.flush();
			buf.close();
			
			msg = new BinaryMessage(buf.toByteArray());
		}


		return msg;
	}

	/**
	 * 读取文本报文
	 * 
	 * @param type 消息头
	 * @return
	 * @throws IOException
	 */
	private Message readTextMessage(int type) throws IOException {
		// 读取数据流，直到发现结束标记（0xff）
		ByteArrayOutputStream buf = new ByteArrayOutputStream();
		for(int b; (b = in.read()) != 0xff; ){
			buf.write(b);
		}
		buf.flush();
		buf.close();

		// 构造文本消息
		String text = new String(buf.toByteArray(), "utf-8");
		Message msg = new TextMessage(text);

		return msg;
	}

}
